import { FormActionType } from '@/basicComp/Form';
import { toRaw, WatchStopHandle } from 'vue';
import { watch, ref, unref, onUnmounted } from 'vue';
import { PaginationProps } from '../types/pagination';
import { BasicTableProps, FetchParams } from '../types/table';
import { TableActionType } from '../types/tableAction';

type UseTableMethod = TableActionType & {
	getForm: () => FormActionType;
};

export function useTable(
	tableProps: BasicTableProps,
): [(instance: TableActionType, formInstance: UseTableMethod) => void, UseTableMethod] {
	const tableRef = ref<Nullable<TableActionType>>(null);
	const loadedRef = ref(false);
	const formRef = ref<Nullable<UseTableMethod>>(null);
	let stopWatch: WatchStopHandle;

	function register(instance: TableActionType, formInstance: UseTableMethod) {
		onUnmounted(() => {
			tableRef.value = null;
			loadedRef.value = false;
		});

		if (unref(loadedRef) && unref(tableRef) === instance) return;

		tableProps && instance.setProps(tableProps);
		tableRef.value = instance;
		formRef.value = formInstance;
		loadedRef.value = true;

		stopWatch?.();

		stopWatch = watch(
			() => tableProps,
			() => {
				tableProps && instance.setProps(tableProps);
			},
			{
				immediate: true,
				deep: true,
			},
		);
	}

	function getTableInstance() {
		const tableInstance = unref(tableRef);
		if (!tableInstance) {
			throw new Error('请先注册table!');
		}
		return tableInstance;
	}

	const methods: UseTableMethod = {
		reload: async (opt?: FetchParams) => {
			return await getTableInstance().reload(opt);
		},
		setProps: (props: Partial<BasicTableProps>) => {
			getTableInstance().setProps(props);
		},
		redoHeight: () => {
			getTableInstance().redoHeight();
		},
		setLoading: (loading: boolean) => {
			getTableInstance().setLoading(loading);
		},
		getDataSource: () => {
			return getTableInstance().getDataSource();
		},
		getRawDataSource: () => {
			return getTableInstance().getRawDataSource();
		},
		getColumns: ({ ignoreIndex = false }: { ignoreIndex?: boolean } = {}) => {
			const columns = getTableInstance().getColumns({ ignoreIndex }) || [];
			return toRaw(columns);
		},
		setDataSource: (values: any[]) => {
			return getTableInstance().setDataSource(values);
		},
		setPagination: (info: Partial<PaginationProps>) => {
			return getTableInstance().setPagination(info);
		},
		deleteSelectRowByKey: (key: string) => {
			getTableInstance().deleteSelectRowByKey(key);
		},
		getSelectRowKeys: () => {
			return toRaw(getTableInstance().getSelectRowKeys());
		},
		getSelectRows: () => {
			return toRaw(getTableInstance().getSelectRows());
		},
		clearSelectedRowKeys: () => {
			getTableInstance().clearSelectedRowKeys();
		},
		setSelectedRowKeys: (keys: string[] | number[]) => {
			getTableInstance().setSelectedRowKeys(keys);
		},
		getPaginationRef: () => {
			return getTableInstance().getPaginationRef();
		},
		updateTableData: (index: number, key: string, value: any) => {
			return getTableInstance().updateTableData(index, key, value);
		},

		updateTableDataRecord: (rowKey: string | number, record: Recordable) => {
			return getTableInstance().updateTableDataRecord(rowKey, record);
		},

		getRowSelection: () => {
			return toRaw(getTableInstance().getRowSelection());
		},

		getForm: () => {
			return unref(formRef) as unknown as FormActionType;
		},
		setShowPagination: async (show: boolean) => {
			getTableInstance().setShowPagination(show);
		},
		getShowPagination: () => {
			return toRaw(getTableInstance().getShowPagination());
		},
		expandAll: () => {
			getTableInstance().expandAll();
		},
		expandRows: (keys: string[]) => {
			getTableInstance().expandRows(keys);
		},
		collapseAll: () => {
			getTableInstance().collapseAll();
		},
		scrollTo: (pos: string) => {
			getTableInstance().scrollTo(pos);
		},
	};
	return [register, methods];
}
